/****************************************************************************
*
*  ALi (Shanghai) Corporation, All Rights Reserved. 2003 Copyright (C)
*
*  File: win_upgrade_menu.c
*
*  Description: 
*              
*  History:
*      Date        	Author             	Version     	Comment
*      ====        	======        	=======   	=======
*
****************************************************************************/
#include <sys_config.h>
#include <types.h>
#include <basic_types.h>
#include <mediatypes.h>
#include <bus/dog/dog.h>
#include <api/libc/printf.h>
#include <api/libc/string.h>
#include <osal/osal.h>
#include <hld/pan/pan_dev.h>
#include <hld/pan/pan.h>

#include <api/libosd/osd_lib.h>
#include <api/libchunk/chunk.h>
#include <api/libupg/p2p_upgrade.h>

#include "osdobjs_def.h"

#include "string.id"
#include "images.id"
#include "osd_config.h"
#include "osd_rsc.h"

#include "win_com.h"

#ifdef SUPPORT_CAS_A
#include "win_com_menu_define.h"
#endif


/*******************************************************************************
* Objects declaration
*******************************************************************************/
CONTAINER win_rs232upg_con;

CONTAINER rs232upg_item_con0; //transfer mode
CONTAINER rs232upg_item_con1;
CONTAINER rs232upg_item_con2;

TEXT_FIELD rs232upg_txt_transfer_type; //transfer mode
TEXT_FIELD rs232upg_txt_upgrade_type;

TEXT_FIELD rs232upg_txt_start;

TEXT_FIELD rs232upg_txt_progress;

TEXT_FIELD rs232upg_txt_msg;


MULTISEL	rs232upg_sel_transfer_type;
MULTISEL	rs232upg_sel_upgrade_type;

PROGRESS_BAR rs232upg_bar_progress;

extern TEXT_FIELD rs232upg_line0;
extern TEXT_FIELD rs232upg_line1;
extern TEXT_FIELD rs232upg_line2;

static VACTION rs232upg_item_sel_keymap(POBJECT_HEAD pObj, UINT32 key);
static PRESULT rs232upg_item_sel_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2);

static VACTION rs232upg_item_keymap(POBJECT_HEAD pObj, UINT32 key);
static PRESULT rs232upg_item_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2);

static VACTION rs232upg_con_keymap(POBJECT_HEAD pObj, UINT32 key);
static PRESULT rs232upg_con_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2);

#ifdef SD_UI	//for 3281 erom upg
#define WIN_SH_IDX	WSTL_WIN_BODYRIGHT_01_HD
#define WIN_HL_IDX	WSTL_WIN_BODYRIGHT_01_HD
#define WIN_SL_IDX	WSTL_WIN_BODYRIGHT_01_HD
#define WIN_GRY_IDX	WSTL_WIN_BODYRIGHT_01_HD


#define CON_SH_IDX	WSTL_BUTTON_01_HD
#define CON_HL_IDX	WSTL_BUTTON_05_HD
#define CON_HL1_IDX	WSTL_BUTTON_02_HD
#define CON_SL_IDX	WSTL_BUTTON_01_HD
#define CON_GRY_IDX	WSTL_BUTTON_07_HD

#define TXTN_SH_IDX   WSTL_BUTTON_01_FG_HD
#define TXTN_HL_IDX   WSTL_BUTTON_02_FG_HD
#define TXTN_SL_IDX   WSTL_BUTTON_01_FG_HD
#define TXTN_GRY_IDX  WSTL_BUTTON_07_HD

#define TXTS_SH_IDX   WSTL_BUTTON_01_FG_HD
#define TXTS_HL_IDX   WSTL_BUTTON_04_HD
#define TXTS_SL_IDX   WSTL_BUTTON_01_FG_HD
#define TXTS_GRY_IDX  WSTL_BUTTON_07_HD



#define PROGRESSBAR_SH_IDX			WSTL_BARBG_01_HD
#define PROGRESSBAR_MID_SH_IDX		WSTL_NOSHOW_IDX
#define PROGRESSBAR_PROGRESS_SH_IDX	WSTL_BAR_01_HD
#define PROGRESS_TXT_SH_IDX	WSTL_BUTTON_01_HD

#define MSG_SH_IDX WSTL_TEXT_09_HD

#define	W_L     	105//384
#define	W_T     	57//138
#define	W_W     	482
#define	W_H     	370

#define CON_L		(W_L+20)
#define CON_T		(W_T + 8)
#define CON_W		(W_W - 40)
#define CON_H		30
#define CON_GAP		8


#define TXTN_L_OF  	10
#define TXTN_W  	180
#define TXTN_H		CON_H
#define TXTN_T_OF	((CON_H - TXTN_H)/2)

#define TXTS_L_OF  	(TXTN_L_OF + TXTN_W)
#define TXTS_W  	(CON_W - TXTN_W-20) //240
#define TXTS_H		CON_H
#define TXTS_T_OF	((CON_H - TXTS_H)/2)


#define BAR_L	(CON_L+5)
#define BAR_T	(CON_T + (CON_H + CON_GAP)*3+10)
#define BAR_W	(CON_W-BAR_TXT_W-10)
#define BAR_H	16

#define BAR_TXT_L (BAR_L + BAR_W + 6)
#define BAR_TXT_W	100//sharon 60
#define BAR_TXT_T ( BAR_T - 6)
#define BAR_TXT_H	36 

#define MSG_L	(CON_L+5)
#define MSG_T	(BAR_T + BAR_H+20)
#define MSG_W	(CON_W-10)
#define MSG_H	CON_H//24
#define MSG_GAP	4

#define LINE_L_OF	0
#define LINE_T_OF  	(CON_H+2)
#define LINE_W		CON_W
#define LINE_H     	2
#else
#define WIN_SH_IDX	WSTL_WIN_BODYRIGHT_01_HD
#define WIN_HL_IDX	WSTL_WIN_BODYRIGHT_01_HD
#define WIN_SL_IDX	WSTL_WIN_BODYRIGHT_01_HD
#define WIN_GRY_IDX	WSTL_WIN_BODYRIGHT_01_HD


#define CON_SH_IDX	WSTL_BUTTON_01_HD
#define CON_HL_IDX	WSTL_BUTTON_05_HD
#define CON_HL1_IDX	WSTL_BUTTON_02_HD
#define CON_SL_IDX	WSTL_BUTTON_01_HD
#define CON_GRY_IDX	WSTL_BUTTON_07_HD

#define TXTN_SH_IDX   WSTL_BUTTON_01_FG_HD
#define TXTN_HL_IDX   WSTL_BUTTON_02_FG_HD
#define TXTN_SL_IDX   WSTL_BUTTON_01_FG_HD
#define TXTN_GRY_IDX  WSTL_BUTTON_07_HD

#define TXTS_SH_IDX   WSTL_BUTTON_01_FG_HD
#define TXTS_HL_IDX   WSTL_BUTTON_04_HD
#define TXTS_SL_IDX   WSTL_BUTTON_01_FG_HD
#define TXTS_GRY_IDX  WSTL_BUTTON_07_HD



#define PROGRESSBAR_SH_IDX			WSTL_BARBG_01_HD
#define PROGRESSBAR_MID_SH_IDX		WSTL_NOSHOW_IDX
#define PROGRESSBAR_PROGRESS_SH_IDX	WSTL_BAR_04_HD
#define PROGRESS_TXT_SH_IDX	WSTL_BUTTON_01_HD

#define MSG_SH_IDX WSTL_TEXT_09_HD

#ifndef SUPPORT_CAS_A /* define in win_com_menu_define.h already */
#define	W_L     	248
#define	W_T     	98
#define	W_W     	692
#define	W_H     	488
#endif

#define CON_L		(W_L+20)
#define CON_T		(W_T + 4)
#define CON_W		(W_W - 60)
#define CON_H		40
#define CON_GAP		12

/*
#define CON_L	(W_L + 4)
#define CON_T	(W_T + 2)
#define CON_W	(W_W - 8)
#define CON_H	28
#define CON_GAP	4
*/
#define TXTN_L_OF  	10
#define TXTN_W  	300//260
#define TXTN_H		40
#define TXTN_T_OF	((CON_H - TXTN_H)/2)

#define TXTS_L_OF  	(TXTN_L_OF + TXTN_W)
#define TXTS_W  	(CON_W - 320) //240
#define TXTS_H		40
#define TXTS_T_OF	((CON_H - TXTS_H)/2)


#define BAR_L	(CON_L+5)
#define BAR_T	(CON_T + (CON_H + CON_GAP)*3+10)
#define BAR_W	(CON_W-BAR_TXT_W-10)
#define BAR_H	24

#define BAR_TXT_L (BAR_L + BAR_W + 6)
#define BAR_TXT_W	100//sharon 60
#define BAR_TXT_T ( BAR_T - 6)
#define BAR_TXT_H	36 

#define MSG_L	(CON_L+5)
#define MSG_T	(BAR_T + BAR_H+20)
#define MSG_W	(CON_W-10)
#define MSG_H	40//24
#define MSG_GAP	4

#define LINE_L_OF	0
#define LINE_T_OF  	(CON_H+4)
#define LINE_W		CON_W
#define LINE_H     	4
#endif

#define LDEF_CON(root, varCon,nxtObj,ID,IDl,IDr,IDu,IDd,l,t,w,h,hl,conobj,focusID)		\
    DEF_CONTAINER(varCon,root,nxtObj,C_ATTR_ACTIVE,0, \
    ID,IDl,IDr,IDu,IDd, l,t,w,h, CON_SH_IDX,hl,CON_SL_IDX,CON_GRY_IDX,   \
    rs232upg_item_keymap,rs232upg_item_callback,  \
    conobj, ID,1)
    
#define LDEF_TXT(root,varTxt,nxtObj,l,t,w,h,resID)		\
    DEF_TEXTFIELD(varTxt,root,nxtObj,C_ATTR_ACTIVE,0, \
    0,0,0,0,0, l,t,w,h, TXTN_SH_IDX,TXTN_HL_IDX,TXTN_SL_IDX,TXTN_GRY_IDX,   \
    NULL,NULL,  \
    C_ALIGN_LEFT | C_ALIGN_VCENTER, 0,0,resID,NULL)

#define LDEF_MSEL(root, varNum, nxtObj, ID, l, t, w, h,style,cur,cnt,ptabl)	\
    DEF_MULTISEL(varNum,root,nxtObj,C_ATTR_ACTIVE,0, \
    ID,ID,ID,ID,ID, l,t,w,h, TXTS_SH_IDX,TXTS_HL_IDX,TXTS_SL_IDX,TXTS_GRY_IDX,   \
    rs232upg_item_sel_keymap,rs232upg_item_sel_callback,  \
    C_ALIGN_CENTER | C_ALIGN_VCENTER, 20,0,style,ptabl,cur,cnt)

#define LDEF_PROGRESS_BAR(root,varBar,nxtObj,l,t,w,h,style,rl,rt,rw,rh)	\
	DEF_PROGRESSBAR(varBar, &root, nxtObj, C_ATTR_ACTIVE, 0, \
		0, 0, 0, 0, 0, l, t, w, h, PROGRESSBAR_SH_IDX, PROGRESSBAR_SH_IDX, PROGRESSBAR_SH_IDX, PROGRESSBAR_SH_IDX,\
		NULL, NULL, style, 0, 0, PROGRESSBAR_MID_SH_IDX, PROGRESSBAR_PROGRESS_SH_IDX, \
		rl,rt , rw, rh, 1, 100, 100, 0)
   
#define LDEF_PROGRESS_TXT(root,varTxt,nxtObj,l,t,w,h)		\
    DEF_TEXTFIELD(varTxt,&root,NULL,C_ATTR_ACTIVE,0, \
    0,0,0,0,0, l,t,w,h, PROGRESS_TXT_SH_IDX,PROGRESS_TXT_SH_IDX,PROGRESS_TXT_SH_IDX,PROGRESS_TXT_SH_IDX,   \
    NULL,NULL,  \
    C_ALIGN_LEFT | C_ALIGN_VCENTER, 0,0,0,display_strs[1])

#define LDEF_TXT_MSG(root,varTxt)		\
    DEF_TEXTFIELD(varTxt,&root,NULL,C_ATTR_ACTIVE,0, \
    0,0,0,0,0,  0,0,0,0, MSG_SH_IDX,0,0,0,   \
    NULL,NULL,  \
    C_ALIGN_LEFT | C_ALIGN_VCENTER, 0,0,0,display_strs[0])
    
#define LDEF_WIN(varCon,nxtObj,l,t,w,h,focusID)		\
    DEF_CONTAINER(varCon,NULL,NULL,C_ATTR_ACTIVE,0, \
    0,0,0,0,0, l,t,w,h, WIN_SH_IDX,WIN_HL_IDX,WIN_SL_IDX,WIN_GRY_IDX,   \
    rs232upg_con_keymap,rs232upg_con_callback,  \
    nxtObj, focusID,0)


#define LDEF_ITEM_SEL(root,varCon,nxtObj,varTxt,varLine,varNum,ID,IDu,IDd,l,t,w,h,\
						hl,resID,style,cur,cnt,ptbl) \
    LDEF_CON(&root,varCon,nxtObj,ID,ID,ID,IDu,IDd,l,t,w,h,hl,&varTxt,ID)   \
    LDEF_TXT(&varCon,varTxt,&varNum,l + TXTN_L_OF,t + TXTN_T_OF,TXTN_W,TXTN_H,resID)    \
    LDEF_MSEL(&varCon,varNum,NULL/*&varLine*/   ,ID, l + TXTS_L_OF ,t + TXTS_T_OF,TXTS_W,TXTS_H,style,cur,cnt,ptbl) \
    LDEF_LINE(&varCon,varLine,NULL,1,1,1,1,1,l + LINE_L_OF, t + LINE_T_OF,LINE_W,LINE_H,0,0)
    
#define LDEF_ITEM_TXT(root,varCon,nxtObj,varTxt,varLine,ID,IDu,IDd,l,t,w,h,\
						hl,resID) \
    LDEF_CON(&root,varCon,nxtObj,ID,ID,ID,IDu,IDd,l,t,w,h,hl,&varTxt,ID)   \
    LDEF_TXT(&varCon,varTxt,NULL/*&varLine*/,l + TXTN_L_OF,t + TXTN_T_OF,TXTN_W,TXTN_H,resID)    \
    LDEF_LINE(&varCon,varLine,NULL,1,1,1,1,1,l + LINE_L_OF, t + LINE_T_OF,LINE_W,LINE_H,0,0)

LDEF_ITEM_SEL(win_rs232upg_con,rs232upg_item_con0,&rs232upg_item_con1,rs232upg_txt_transfer_type,rs232upg_line0,rs232upg_sel_transfer_type,\
	1,3,2,CON_L, CON_T + (CON_H + CON_GAP)*0,CON_W,CON_H,CON_HL_IDX,RS_TOOLS_TRANSFER_MODE,STRING_ANSI,0,0,NULL)

LDEF_ITEM_SEL(win_rs232upg_con,rs232upg_item_con1,&rs232upg_item_con2,rs232upg_txt_upgrade_type,rs232upg_line1,rs232upg_sel_upgrade_type,\
	2,1,3,CON_L, CON_T + (CON_H + CON_GAP)*1,CON_W,CON_H,CON_HL_IDX,RS_TOOLS_UPGRADE_MODE,STRING_ANSI,0,0,NULL)

#ifdef SD_UI
LDEF_ITEM_TXT(win_rs232upg_con,rs232upg_item_con2,&rs232upg_bar_progress,rs232upg_txt_start,rs232upg_line2, \
	3,2,1,CON_L, CON_T + (CON_H + CON_GAP)*2,CON_W,CON_H,CON_HL_IDX,RS_COMMON_START)
#else	
LDEF_ITEM_TXT(win_rs232upg_con,rs232upg_item_con2,&rs232upg_bar_progress,rs232upg_txt_start,rs232upg_line2, \
	3,2,1,CON_L, CON_T + (CON_H + CON_GAP)*2,CON_W,CON_H,CON_HL1_IDX,RS_COMMON_START)
#endif

#ifndef SD_UI
LDEF_PROGRESS_BAR(win_rs232upg_con,rs232upg_bar_progress,&rs232upg_txt_progress,	\
		BAR_L, BAR_T, BAR_W, BAR_H, PROGRESSBAR_HORI_NORMAL | PBAR_STYLE_RECT_STYLE,2,5,BAR_W - 4,BAR_H - 10)
#else
LDEF_PROGRESS_BAR(win_rs232upg_con,rs232upg_bar_progress,&rs232upg_txt_progress,	\
		BAR_L, BAR_T, BAR_W, BAR_H, PROGRESSBAR_HORI_NORMAL | PBAR_STYLE_RECT_STYLE,2,2,BAR_W - 4,BAR_H-4)
#endif

LDEF_PROGRESS_TXT(win_rs232upg_con, rs232upg_txt_progress, NULL, \
		BAR_TXT_L, BAR_TXT_T, BAR_TXT_W, BAR_TXT_H)

LDEF_TXT_MSG(win_rs232upg_con,rs232upg_txt_msg)

LDEF_WIN(win_rs232upg_con,&rs232upg_item_con0,W_L,W_T,W_W,W_H,3)

#define TRANSFER_ID 1
#define START_ID 3//2   
/*******************************************************************************
*	Local functions & variables declare
*******************************************************************************/

#define RS232UPG_MSG_MAX_LINE 5//6

static char ** rs232upg_upgtype_chars = NULL;
static char ** rs232upg_transfertype_chars = NULL;
static UINT16 *rs232upg_msg_buf[RS232UPG_MSG_MAX_LINE+1];
static UINT32 rs232upg_msg_line ;

static void win_rs232upg_load_chunk_info()
{
	CHUNK_HEADER blk_header;
	UINT32 id,mask;
	UINT8 chunk_number;
	UINT8 i;
#if (defined HDCP_IN_FLASH || !defined UPG_MEMCFG_SUPPORT)
	UINT32 Block_id = 0, HDCP_key_ID = 0,ciplus_key_ID = 0;
	UINT8 hdcp_chunk_index = 0;
    UINT8 cipluskey_chunk_index = 0;
    
	BOOL has_hdcp_chunk = FALSE;
    BOOL has_cipluskey_chunk = FALSE;

    UINT32 memcfg_ID = 0;
    UINT8 memcfg_chunk_index = 0;
    BOOL has_memcfg_chunk = FALSE;

	UINT32 special_type =0;
#endif
 
	chunk_number = sto_chunk_count(0,0);
	if(chunk_number == 0)
		return;

	if(InitBlockList() != SUCCESS)
		return;

	if(rs232upg_upgtype_chars != NULL)
		FREE(rs232upg_upgtype_chars);
	rs232upg_upgtype_chars = (char**)MALLOC(sizeof(char*)*chunk_number);
	if(rs232upg_upgtype_chars == NULL)
		ASSERT(0);
	for(i=0; i<chunk_number; i++)
	{
		rs232upg_upgtype_chars[i] = (char*)MALLOC(16*sizeof(char));
		if(rs232upg_upgtype_chars[i] == NULL)
			ASSERT(0);
	}
		
	STRCPY(rs232upg_upgtype_chars[0],"allcode");
	
	if(rs232upg_transfertype_chars != NULL)
		FREE(rs232upg_transfertype_chars);
	rs232upg_transfertype_chars = (char**)MALLOC(sizeof(char*)*2);
	if(rs232upg_transfertype_chars == NULL)
		ASSERT(0);
	for(i=0;i<2;i++)
	{
		rs232upg_transfertype_chars[i] = (char*)MALLOC(16*sizeof(char));
		if(rs232upg_transfertype_chars[i] == NULL)
			ASSERT(0);
	}
	STRCPY(rs232upg_transfertype_chars[0],"P2P");

	
	for(i=1; i<chunk_number; i++)
	{
		id = mask = 0;
#if (defined HDCP_IN_FLASH)		
         special_type = 0;
#endif
		sto_chunk_goto(&id,mask,i + 1);
		sto_get_chunk_header(id, &blk_header);

#if (defined HDCP_IN_FLASH || defined CI_PLUS_SUPPORT || !defined UPG_MEMCFG_SUPPORT)
#ifdef HDCP_IN_FLASH
		HDCP_key_ID = HDCPKEY_CHUNK_ID;
		if(((UINT32)blk_header.id) == HDCP_key_ID)
		{
			hdcp_chunk_index = i;
			has_hdcp_chunk = TRUE;
			special_type = 1;
		}
#endif
#ifdef CI_PLUS_SUPPORT
        ciplus_key_ID = CIPLUSKEY_CHUNK_ID;
        if(((UINT32)blk_header.id) == ciplus_key_ID)
        {
            cipluskey_chunk_index = i;
            has_cipluskey_chunk = TRUE;
            special_type = 1;
        }
#endif

#ifdef MEMCFG_CHUNK_ID
#ifndef UPG_MEMCFG_SUPPORT
    if((ALI_S3503==sys_ic_get_chip_id())||(ALI_S3821==sys_ic_get_chip_id()))
    {
        memcfg_ID = MEMCFG_CHUNK_ID;
        if(((UINT32)blk_header.id) == memcfg_ID)
        {
            memcfg_chunk_index = i;
            has_memcfg_chunk = TRUE;
            special_type = 1;
        }
    }
#endif
#endif
		if(special_type != 1)
			STRCPY(rs232upg_upgtype_chars[i], blk_header.name);
		
#else
		STRCPY(rs232upg_upgtype_chars[i],blk_header.name);
#endif
	}

#ifdef _S3281_	
	STRCPY(rs232upg_upgtype_chars[0], "Flash Prog & BL Enc");
	STRCPY(rs232upg_upgtype_chars[1], "Flash Prog");
	STRCPY(rs232upg_upgtype_chars[2], "BL Enc");
	OSD_SetMultiselSelTable(&rs232upg_sel_upgrade_type,rs232upg_upgtype_chars);
	OSD_SetMultiselCount(&rs232upg_sel_upgrade_type, 3);

	STRCPY(rs232upg_transfertype_chars[0], "P2P");
	STRCPY(rs232upg_transfertype_chars[1], "P2M");
	OSD_SetMultiselSelTable(&rs232upg_sel_transfer_type,rs232upg_transfertype_chars);
	OSD_SetMultiselCount(&rs232upg_sel_transfer_type, 2);
#else
#ifdef HDCP_IN_FLASH
	if(has_hdcp_chunk == TRUE)
	{
		FREE(rs232upg_upgtype_chars[hdcp_chunk_index]);
		for(i=hdcp_chunk_index; i<chunk_number;i++)
			rs232upg_upgtype_chars[i] = rs232upg_upgtype_chars[i+1];
		chunk_number--;
        if( (has_cipluskey_chunk == TRUE) && hdcp_chunk_index < cipluskey_chunk_index)
            cipluskey_chunk_index --;
        if((has_memcfg_chunk == TRUE)&& hdcp_chunk_index < memcfg_chunk_index)
            memcfg_chunk_index --;
	}
#endif

#ifndef UPG_MEMCFG_SUPPORT
    if((ALI_S3503==sys_ic_get_chip_id())||(ALI_S3821==sys_ic_get_chip_id()))
    {
        if(has_memcfg_chunk == TRUE)
        {
            FREE(rs232upg_upgtype_chars[memcfg_chunk_index]);
            for(i=memcfg_chunk_index; i<chunk_number;i++)
                rs232upg_upgtype_chars[i] = rs232upg_upgtype_chars[i+1];
            chunk_number--;    
            if( (has_cipluskey_chunk == TRUE) && memcfg_chunk_index < cipluskey_chunk_index)
            cipluskey_chunk_index --;  
        }
    }
#endif

#ifdef CI_PLUS_SUPPORT
        if(has_cipluskey_chunk == TRUE)
        {
            FREE(rs232upg_upgtype_chars[cipluskey_chunk_index]);
            for(i=cipluskey_chunk_index; i<chunk_number;i++)
                rs232upg_upgtype_chars[i] = rs232upg_upgtype_chars[i+1];
            chunk_number--;
        }
#endif

	OSD_SetMultiselSelTable(&rs232upg_sel_upgrade_type,rs232upg_upgtype_chars);
	OSD_SetMultiselCount(&rs232upg_sel_upgrade_type, chunk_number);
	OSD_SetMultiselSelTable(&rs232upg_sel_transfer_type,rs232upg_transfertype_chars);
	OSD_SetMultiselCount(&rs232upg_sel_transfer_type, 2);
#endif
	
	
}

static void win_rs232upg_clear()
{
	UINT8 i,chunk_number;
	
	chunk_number = sto_chunk_count(0,0);
#ifdef HDCP_IN_FLASH
	chunk_number--;
#endif	
	if(rs232upg_upgtype_chars != NULL)
	{
		for(i=0;i<chunk_number;i++)
			FREE(rs232upg_upgtype_chars[i]);
		FREE(rs232upg_upgtype_chars);

		rs232upg_upgtype_chars = NULL;
	}
}

static void win_rs232upg_process_update(INT32 process)
{

#ifdef WATCH_DOG_SUPPORT
    dog_set_time(0, 0);
#endif

	if(process > 100)
		process = 0;

	OSD_SetProgressBarPos(&rs232upg_bar_progress,(INT16)process);
	OSD_SetTextFieldContent(&rs232upg_txt_progress, STRING_NUM_PERCENT, (UINT32)process);

	OSD_DrawObject( (POBJECT_HEAD)&rs232upg_bar_progress, C_UPDATE_ALL);
	OSD_DrawObject( (POBJECT_HEAD)&rs232upg_txt_progress, C_UPDATE_ALL);
}

static void win_rs232upg_msg_update(UINT8 * str)
{
	UINT32 i,j;
	OSD_RECT rect;

	ComAscStr2Uni(str, display_strs[10+rs232upg_msg_line%RS232UPG_MSG_MAX_LINE]);

	for(i=0; i<RS232UPG_MSG_MAX_LINE; i++)
	{
		if(rs232upg_msg_line<RS232UPG_MSG_MAX_LINE)
			j = i%RS232UPG_MSG_MAX_LINE;
		else
			j = (rs232upg_msg_line+1+i)%RS232UPG_MSG_MAX_LINE;
		
		rs232upg_msg_buf[i] = display_strs[10+j];
	}
	
		//draw msg infos
	for(i=0; i<RS232UPG_MSG_MAX_LINE; i++)
	{
		rect.uLeft 	= MSG_L;
		rect.uTop  	= MSG_T+(MSG_H+MSG_GAP)*i;
		rect.uWidth = MSG_W;
		rect.uHeight= MSG_H;

		OSD_SetRect2(&rs232upg_txt_msg.head.frame, &rect);
		OSD_SetTextFieldContent(&rs232upg_txt_msg, STRING_UNICODE, (UINT32)rs232upg_msg_buf[i]);
		OSD_DrawObject( (POBJECT_HEAD)&rs232upg_txt_msg, C_UPDATE_ALL);
	}
	
	rs232upg_msg_line++;;
}

static void win_rs232upg_msg_clear()
{
	UINT8 i;
	OSD_RECT rect;
	
	for(i=0;i<RS232UPG_MSG_MAX_LINE;i++)
	{
		ComAscStr2Uni("", display_strs[10+i]);
		rs232upg_msg_buf[i] = display_strs[10+i];

		rect.uLeft 	= MSG_L;
		rect.uTop  	= MSG_T+(MSG_H+MSG_GAP)*i;
		rect.uWidth = MSG_W;
		rect.uHeight= MSG_H;

		OSD_SetRect2(&rs232upg_txt_msg.head.frame, &rect);
		OSD_SetTextFieldContent(&rs232upg_txt_msg, STRING_UNICODE, (UINT32)rs232upg_msg_buf[i]);
		OSD_DrawObject( (POBJECT_HEAD)&rs232upg_txt_msg, C_UPDATE_ALL);
	}

 	rs232upg_msg_line = 0;	
}

void win_rs232upg_update(INT32 type, INT32 process, UINT8 *str)
{
	UINT32 vscr_idx;
	lpVSCR apVscr;
	
	vscr_idx = osal_task_get_current_id();
	apVscr = OSD_GetTaskVscr(vscr_idx);
	switch(type)
	{
		case 1:
			win_rs232upg_process_update(process);
			break;
		case 2:
			win_rs232upg_msg_update(str);
			break;
		case 3:
			win_rs232upg_process_update(process);
			win_rs232upg_msg_update(str);
			break;
		default:
			break;
	}

	OSD_UpdateVscr(apVscr);
}

UINT32 upg_check_exit_key(void)
{
	UINT32 hkey,vkey;
    struct pan_key key_struct;

    if(key_get_key(&key_struct, 0))
    {
		hkey = scan_code_to_msg_code(&key_struct);
        ap_hk_to_vk(0,hkey, &vkey);
        if(vkey == V_KEY_EXIT ||  vkey==V_KEY_MENU)
            return 1;
	 else if(V_KEY_ENTER == vkey)	
	     return 2;	
    }

    return 0;
}

static void win_rs232upg_start()
{
	UINT16 channel;

	OSD_SetProgressBarPos(&rs232upg_bar_progress,(INT16)0);
	OSD_SetTextFieldContent(&rs232upg_txt_progress, STRING_NUM_PERCENT, (UINT32)0);

	sys_upgrade(win_rs232upg_update,upg_check_exit_key/*UIGetExitKey*/);
	FreeSlavelist();
	if(screen_back_state == SCREEN_BACK_VIDEO)
	{
		channel = sys_data_get_cur_group_cur_mode_channel();
		api_play_channel(channel, TRUE, TRUE,FALSE);
	}
}
/*******************************************************************************
*	Window's keymap, proc and  callback
*******************************************************************************/
static VACTION rs232upg_item_sel_keymap(POBJECT_HEAD pObj, UINT32 key)
{
	VACTION act;
	
	switch(key)
	{
		case V_KEY_LEFT:
			act = VACT_DECREASE;
			break;
		case V_KEY_RIGHT:
			act = VACT_INCREASE;
			break;
		default:
			act = VACT_PASS;
	}

#ifndef _S3281_
	UINT8 bID;
	bID = OSD_GetObjID(pObj);
	if(TRANSFER_ID == bID)
		act = VACT_PASS;
#endif

	return act;	

}

static PRESULT rs232upg_item_sel_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	PRESULT ret = PROC_PASS;

	return ret;
}

static VACTION rs232upg_item_keymap(POBJECT_HEAD pObj, UINT32 key)
{
	VACTION act;
	switch(key)
	{
	case V_KEY_ENTER:
	case V_KEY_RIGHT:		
		act = VACT_ENTER;
		break;
	default:
		act = VACT_PASS;
	}

	return act;
}
#if( ( ((defined _S3281_) || (defined _M3503_)) && (defined(_EROM_UPG_HOST_ENABLE_)) ) && defined ENABLE_EROM)
extern UINT32 set_upgrade_mode(UINT32 mode);
#endif

static PRESULT rs232upg_item_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	PRESULT ret = PROC_PASS;
	VACTION unact;
	UINT8 bID;

	bID = OSD_GetObjID(pObj);

	switch(event)
	{
		case EVN_UNKNOWN_ACTION:
			unact = (VACTION)(param1>>16);
			if(unact == VACT_ENTER && bID == START_ID)
			{
				system_state = SYS_STATE_UPGRAGE_HOST;

				OSD_SetAttr(&rs232upg_item_con0, C_ATTR_INACTIVE);
				OSD_SetAttr(&rs232upg_item_con1, C_ATTR_INACTIVE);
				OSD_SetAttr(&rs232upg_item_con2, C_ATTR_INACTIVE);
				OSD_DrawObject( (POBJECT_HEAD)&rs232upg_item_con0, C_UPDATE_ALL);
				OSD_DrawObject( (POBJECT_HEAD)&rs232upg_item_con1, C_UPDATE_ALL);
				OSD_DrawObject( (POBJECT_HEAD)&rs232upg_item_con2, C_UPDATE_ALL);

				ClearUpgFlag();
			
				if(OSD_GetMultiselSel(&rs232upg_sel_upgrade_type) == 0)
				{
				#if(defined(MULTI_CAS) && defined(SUPPORT_CAS_A))
					p2p_enable_upgrade_bootloader(FALSE);
				#else
                    p2p_enable_upgrade_bootloader(TRUE);
				#endif
						if(InitBlockList() != SUCCESS)
							return PROC_LEAVE;											
					SetUpgFlag(0, 0, 1);
				}
				else
				{					
					p2p_enable_upgrade_bootloader(FALSE);
					if(InitBlockList() != SUCCESS)
						return PROC_LEAVE;							 
					SetUpgFlag(Index2Id(OSD_GetMultiselSel(&rs232upg_sel_upgrade_type)), 0xFFFFFFFF, 1);
				}
				
		#if( ( ((defined _S3281_) || (defined _M3503_)) && (defined(_EROM_UPG_HOST_ENABLE_)) ) && defined ENABLE_EROM )			
				UINT32 upg_mode = OSD_GetMultiselSel(&rs232upg_sel_upgrade_type);
				set_upgrade_mode(upg_mode);
				
				UINT32 transfer_sel = OSD_GetMultiselSel(&rs232upg_sel_transfer_type);
				if(0==transfer_sel)
					set_transfer_mode(UPGRADE_SINGLE);
				else	
					set_transfer_mode(UPGRADE_MULTI);
		#endif		
				
				//start transfer
				//add by bill 2012.02.24
				//add for M3812 T2/M3823
				#if (SYS_MAIN_BOARD == BOARD_DB_M3601B_01V01 || SYS_MAIN_BOARD == BOARD_DB_M3812_03V01 \
                     || SYS_MAIN_BOARD == BOARD_DB_M3823_01V01 || SYS_MAIN_BOARD == BOARD_DB_M3823_02V01)
    					api_uart_enable(TRUE);	
				#endif
				win_rs232upg_start();
			
				#if (SYS_MAIN_BOARD == BOARD_DB_M3601B_01V01 || SYS_MAIN_BOARD == BOARD_DB_M3812_03V01 \
                     || SYS_MAIN_BOARD == BOARD_DB_M3823_01V01 || SYS_MAIN_BOARD == BOARD_DB_M3823_02V01)
    					api_uart_enable(FALSE);	
				#endif				
				OSD_SetAttr(&rs232upg_item_con0, C_ATTR_ACTIVE);
				OSD_SetAttr(&rs232upg_item_con1, C_ATTR_ACTIVE);
				OSD_SetAttr(&rs232upg_item_con2, C_ATTR_ACTIVE);
				OSD_DrawObject( (POBJECT_HEAD)&rs232upg_item_con0, C_UPDATE_ALL);
				OSD_DrawObject( (POBJECT_HEAD)&rs232upg_item_con1, C_UPDATE_ALL);
				OSD_TrackObject( (POBJECT_HEAD)&rs232upg_item_con2, C_UPDATE_ALL);

				system_state = SYS_STATE_NORMAL;
			}
			break;
	}

	return ret;
}

static VACTION rs232upg_con_keymap(POBJECT_HEAD pObj, UINT32 vkey)
{
	VACTION act;
	
	switch(vkey)
	{
	case V_KEY_UP:
		act = VACT_CURSOR_UP;
		break;
	case V_KEY_DOWN:
		act = VACT_CURSOR_DOWN;
		break;		
	case V_KEY_EXIT:
	case V_KEY_MENU:
		if((ALI_S3281==sys_ic_get_chip_id()) && check_rs232_item_is_active()) 
			act = VACT_PASS;
		else				
			act = VACT_CLOSE;
		break;
	default:	
		act = VACT_PASS;
		break;
	}

	return act;
}

static PRESULT rs232upg_con_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	PRESULT ret = PROC_PASS;
	CONTAINER* cont = (CONTAINER*)pObj;
	UINT8	id = OSD_GetObjID(pObj);

	switch(event)
	{
		case EVN_PRE_OPEN:
			wincom_open_title((POBJECT_HEAD)&win_rs232upg_con,RS_UPGRADE_MODE_RS232, 0);
			win_rs232upg_load_chunk_info();
			OSD_SetProgressBarPos(&rs232upg_bar_progress,(INT16)0);
			OSD_SetTextFieldContent(&rs232upg_txt_progress, STRING_NUM_PERCENT, (UINT32)0);

			break;
			
		case EVN_POST_OPEN:
			win_rs232upg_msg_clear();
			break;
		
		case EVN_PRE_CLOSE:
			win_rs232upg_clear();
			/* Make OSD not flickering */
			*((UINT32*)param2) &= ~C_CLOSE_CLRBACK_FLG;	
			
			break;

		case EVN_POST_CLOSE:
			break;
	}
	return ret;
}

